package com.xique.door.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xique.common.core.domain.R;
import com.xique.common.core.utils.OrikaUtil;
import com.xique.common.core.utils.StringUtils;
import com.xique.common.core.utils.json.JSONObject;
import com.xique.common.core.web.domain.AjaxResult;
import com.xique.door.api.dto.BaseUserDTO;
import com.xique.door.api.dto.ProjectDTO;
import com.xique.door.api.model.LoginAppUser;
import com.xique.door.bean.domain.*;
import com.xique.door.biz.service.IBaseUserBizService;
import com.xique.door.service.IBaseUserService;
import com.xique.door.service.IParkInfoService;
import com.xique.door.service.IUserService;
import com.xique.door.service.IWxUserService;
import com.xique.door.util.WechatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author shd
 * @create 2021/12/31 11:34
 */
@Service
public class BaseUserBizServiceImpl implements IBaseUserBizService {

    @Autowired
    private IBaseUserService baseUserService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IParkInfoService parkInfoService;

    @Autowired
    private WechatUtils wechatUtils;

    @Value("${wx.gzh.appId}")
    private String appId;

    @Value("${wx.gzh.secret}")
    private String secret;

    @Autowired
    private IWxUserService wxUserService;

    @Override
    public R<LoginAppUser> getAppUserByLoginName(String loginName) {

        BaseUser user = baseUserService.selectBaseUserByLoginName(loginName);

        if (StringUtils.isNull(user)) {
            return R.fail("用户名或密码错误");
        }

        List<User> userList = userService.selectUserByBaseUserId(user.getId());
        List<Long> parkIds = userList.stream().map(User::getParkId).distinct().collect(Collectors.toList());
        Map<Long, Long> parkUserMap = userList.stream().collect(Collectors.toMap(User::getParkId, User::getId));

        List<ParkInfo> parkInfoList = parkInfoService.selectParkInfoByIds(parkIds);

        BaseUserDTO dto = OrikaUtil.convert(user, BaseUserDTO.class);
        List<ProjectDTO> dtos = OrikaUtil.converts(parkInfoList, ProjectDTO.class);
        dtos.forEach(item -> {
            if (StringUtils.isNotNull(parkUserMap.get(item.getId()))) {
                item.setUserId(parkUserMap.get(item.getId()));
            }
        });

        dto.setProjects(dtos);

        LoginAppUser loginAppUser = new LoginAppUser();
        loginAppUser.setUserId(dto.getId());
        loginAppUser.setUserName(dto.getUserName());
        loginAppUser.setUser(dto);

        return R.ok(loginAppUser);
    }

    @Override
    public AjaxResult getGzhUserInfo(String openId) {

        JSONObject object = wechatUtils.getGzhOpenIds(appId, secret, openId);

        List<WxUser> list = new ArrayList<>();
        JSONObject.JSONArray array = object.getObj("data").getArr("openid");
        array.forEach(item -> {
            WxUser user = new WxUser();
            user.setOpenId(item.toString());
            list.add(user);
        });
        String nextOpenId = object.getStr("next_openid");
        while (StringUtils.isNotEmpty(nextOpenId)) {
            JSONObject object1 = wechatUtils.getGzhOpenIds(appId, secret, nextOpenId);

            nextOpenId = object1.getStr("next_openid");
            if (StringUtils.isEmpty(nextOpenId)) {
                break;
            }

            JSONObject.JSONArray array1 = object1.getObj("data").getArr("openid");
            array1.forEach(item -> {
                WxUser user = new WxUser();
                user.setOpenId(item.toString());
                list.add(user);
            });
        }

        List<WxUser> userList = wxUserService.list();
        List<String> openIds = userList.stream().map(WxUser::getOpenId).distinct().collect(Collectors.toList());
        List<WxUser> realList = list.stream().filter(v -> !openIds.contains(v.getOpenId())).collect(Collectors.toList());

        wxUserService.saveBatch(realList);

        return AjaxResult.success();
    }

    @Override
    public AjaxResult getGzhUserInfoV1() {

        QueryWrapper<WxUser> condition = new QueryWrapper<>();
        condition.isNull("union_id");
        List<WxUser> list = wxUserService.list(condition);
        List<WxUser> updateList = new ArrayList<>();

        AtomicInteger count = new AtomicInteger();
        list.forEach(item -> {
            JSONObject object = wechatUtils.getGzhUserInfo(appId, secret, item.getOpenId());
            if (StringUtils.isNotEmpty(object.getStr("unionid"))) {
                WxUser update = new WxUser();
                update.setId(item.getId());
                update.setUnionId(object.getStr("unionid"));
                updateList.add(update);
            }

            count.getAndIncrement();
            if (count.get() % 1000 == 0) {
                wxUserService.updateBatchById(updateList);
                updateList.clear();
            }
        });

        wxUserService.updateBatchById(updateList);

        return AjaxResult.success();
    }
}
